<?php
// +----------------------------------------------------------------------
// | Variable 自定义服务
// +----------------------------------------------------------------------
// | 主要服务于Variable数据处理
// +----------------------------------------------------------------------
// | 错误编码头 230xxx
// +----------------------------------------------------------------------

namespace common\service;

use common\model\EntityModel;
use common\model\FieldModel;
use common\model\ModuleModel;
use think\Cache;
use think\Db;

class FieldService
{

    /**
     * @var \common\model\FieldModel
     */
    protected $fieldModel;

    // 排除模块
    protected $exclusionModule = ['tenant', 'module'];


    public function __construct()
    {
        $this->fieldModel = model(FieldModel::class);
    }

    /**
     * 获取table list
     * @return mixed
     */
    public function getTableList()
    {
        // 获取固定表和自定义表列表
        $moduleModel = model(ModuleModel::class);
        $resData = $moduleModel->field('id,type,code')->select();
        return $resData;
    }

    /**
     * 获取单张表配置
     * @param $tableName
     * @return array
     */
    public function getFieldConfig($tableName = '')
    {
        if (!empty($tableName)) {
            // 判断是否传入表名称
            $resData = $this->fieldModel->getTableFields($tableName);
        } else {
            $resData = ["total" => 0, "rows" => []];
        }
        return $resData;
    }

    /**
     * 修改
     * @param string $tableName
     * @param array $config
     * @return array
     * @throws \think\Exception
     */
    public function modifyFieldConfig($tableName = '', $config = [])
    {
        $resData = $this->fieldModel->modifyFieldConfig($tableName, $config);
        return $resData;
    }

    /**
     * 创建自定义字段
     * @param $param
     * @return mixed
     * @throws \think\Exception
     */
    public function createCustomField($param)
    {
        $resData = $this->fieldModel->createCustomField($param);
        return $resData;
    }


    /**
     * 获取自定义字段类型列表
     * @return array
     */
    public function getCustomFieldTypeList()
    {
        $listData = [
            [ // 输入框
                "id" => "input",
                "name" => "input"
            ],
            [ // 标签
                "id" => "tag",
                "name" => "tag"
            ],
            [ // link 链接
                "id" => "link",
                "name" => "link"
            ],
            [ // 下拉框
                "id" => "select",
                "name" => "select"
            ],
            [ // 多行文本
                "id" => "text_area",
                "name" => "text_area"
            ],
            [ // 富文本
                "id" => "rich_text",
                "name" => "rich_text"
            ],
            [ // 上传
                "id" => "upload",
                "name" => "upload"
            ],
            [ // 工时
                "id" => "times",
                "name" => "times"
            ],
            [ // 时间日期
                "id" => "date",
                "name" => "date"
            ],
            [ // 开关
                "id" => "switch",
                "name" => "switch"
            ],
            [ // 单选框
                "id" => "radio",
                "name" => "radio"
            ],
            [ // 复选框
                "id" => "checkbox",
                "name" => "checkbox"
            ],
            [ // 水平关联
                "id" => "horizontal_relation",
                "name" => "horizontal_relation"
            ],
            [ // 规格
                "id" => "attribute",
                "name" => "attribute"
            ]
        ];

        return $listData;
    }

    /**
     * 获取自定义下拉框可以关联模块列表数据
     * @return array
     */
    public function getSelectModuleList()
    {
        $cantHorizontalModuleCodeList = ['user,status,tag,media'];

        $moduleModel = model(ModuleModel::class);
        $listData = $moduleModel->field('id,type,name,code')->where(["code" => ["IN", join(',', $cantHorizontalModuleCodeList)]])->select();

        return $listData;
    }

    /**
     * 获取自定义水平可以关联模块列表数据
     * @return array
     */
    public function getHorizontalModuleList()
    {
        $cantHorizontalModuleCodeList = ['user,status,media,tag'];

        $moduleModel = model(ModuleModel::class);
        $listData = $moduleModel->field('id,type,name,code')->where(["code" => ["IN", join(',', $cantHorizontalModuleCodeList)]])->select();

        return $listData;
    }

    /**
     * 递归处理
     * @param $relationModuleFields
     * @param $relationItem
     */
    protected function recursiveExcelImportFields(&$relationModuleFields, $relationItem)
    {
        if ($relationItem['filter_type'] === 'entity') {
            $moduleCode = $relationItem['belong_module'];
        } else {
            $moduleCode = $relationItem['module_code'];
        }

        if (!in_array($moduleCode, $this->exclusionModule)) {
            $tempFields = $this->getFieldConfig($moduleCode);
            $allowEditField = [];

            foreach ($tempFields as $field) {
                if ($field['edit'] === 'allow') {
                    $allowEditField[] = $field;
                }
            }

            $relationModuleFields[$moduleCode] = $allowEditField;

            if (array_key_exists('child', $relationItem) && !empty($relationItem['child'])) {
                $this->recursiveExcelImportFields($relationModuleFields, $relationItem['child']);
            }
        }
    }

    /**
     * 获取指定模块的字段
     * @param $moduleCode
     * @return array
     */
    public function getExcelImportFields($moduleCode)
    {
        // 获取指定模块字段
        $relationModel = model(EntityModel::class);
        $relationModel->setCurrentModuleCode($moduleCode);
        $relationModule = $relationModel->parserFilterModuleRelation(true);

        $relationModuleFields = [];
        foreach ($relationModule as $relationItem) {
            $this->recursiveExcelImportFields($relationModuleFields, $relationItem);
        }

        return $relationModuleFields;
    }

    /**
     * 生成模块字段缓存
     * @return array
     */
    public function generateModuleFieldCache()
    {
        // 获取所有注册模块
        $moduleModel = model(ModuleModel::class);
        $moduleList = $moduleModel->selectData(['fields' => 'id,type,name,code,uuid']);

        $moduleDictData = [];
        $moduleDictData['module_index_by_id'] = array_column($moduleList["rows"], null, 'id');
        $moduleDictData['module_index_by_code'] = array_column($moduleList["rows"], null, 'code');


        // 获取所有模块字段
        $fieldModel = model(FieldModel::class);
        $moduleDictData['field_index_by_code'] = $fieldModel->getAllModuleFieldsMapData($moduleDictData['module_index_by_id']);

        // 写入缓存
        Cache::set('module_field_dict_data', $moduleDictData);

        return $moduleDictData;
    }


    /**
     * 自动刷新字典配置和缓存
     * @throws \think\Exception
     */
    public function autoFixFieldConfigAndCache()
    {
        $moduleModel = model(ModuleModel::class);
        $moduleList = $moduleModel->field('code')->select();

        // 获取最新字段配置然后写回去
        foreach ($moduleList as $item) {
            try {
                $newFields = $this->getFieldConfig($item['code']);
            } catch (\Throwable $e) {
                continue;
            }


            // 分开固定字段和自定义字段
            $saveFields = [
                'custom' => [],
                'fixed' => []
            ];
            foreach ($newFields as $field) {
                if ($field['field_type'] === 'built_in') {
                    $saveFields['fixed'][] = $field;
                } else {
                    $saveFields['custom'][] = $field;
                }
            }

            // 更新字段配置
            $this->modifyFieldConfig($item['code'], $saveFields);
        }

        // 更新模块字段缓存
        $this->generateModuleFieldCache();
    }
}
